package kadledav.adventure.framework.builder.name;

import java.util.HashMap;
import java.util.Map;

import kadledav.adventure.framework.controll.CommandLineControll;
import kadledav.adventure.framework.model.controll.GameWrapper;
import kadledav.adventure.framework.model.controll.GameWrapperBasic;
import kadledav.adventure.framework.model.world.Item;
import kadledav.adventure.framework.model.world.Location;
import kadledav.adventure.framework.model.world.Player;
import kadledav.adventure.framework.model.world.impl.LocationBasic;
import kadledav.adventure.framework.model.world.impl.PlayerBasic;

public class SimpleNameBuilder {
	
	private Map<String,LocationBasic> locations = new HashMap<String,LocationBasic>();
	private Map<String,Item> associatedItems = new HashMap<String,Item>();
	private Map<String,SimpleNameItem> items = new HashMap<String,SimpleNameItem>();
	private SimpleNameBuilderPassage passageBuilder = new SimpleNameBuilderPassage();
	private GameWrapper gameWrapper;
	
	public void throwGeneralBuilderException(){
		throw new RuntimeException("Build opration could not be completed");
	}
	
	public void createLocation(String name, String description){
		if(locations.get("name")!=null){			
			throwGeneralBuilderException();
		}
		locations.put(name, new LocationBasic(name, description));
	}
	
	public void createItem(String name, String description){
		adddItemToItems(name, new SimpleNameItem(name, description,true));
	}
	
	public void createStaticItem(String name, String description){
		adddItemToItems(name, new SimpleNameItem(name, description,false));
	}

	private void adddItemToItems(String name, SimpleNameItem simpleNameItem) {
		if(items.get("name")!=null){
			throwGeneralBuilderException();
		}
		items.put(name,simpleNameItem);
	}
	
	public void addItemsToLoaction(String locationName,String... itemNames){
		if(locations.get(locationName)==null){
			throwGeneralBuilderException();
		}
		for (String itemName : itemNames) {
			SimpleNameItem item = items.get(itemName);
			if (associatedItems.get(itemName)!=null || item==null ){
				throwGeneralBuilderException();
			}
			locations.get(locationName).addItem(item);		
		}
	}
	
	public void createConnection(String location1,String location2, final String passageName){
		passageBuilder.createConnection(locations.get(location1), locations.get(location2), passageName);
	}
	
	public void createConnectionWithLock(String location1,String location2, String passageName, String newPassageName, final String unlockWithItem){
		passageBuilder.createConnectionWithLock(locations.get(location1), locations.get(location2), passageName,newPassageName, unlockWithItem);
	}
	
	public void createConnectionOneDir(String locationFrom,String locationTo, String passageName){
		passageBuilder.createConnectionOneDir(locations.get(locationFrom), locations.get(locationTo), passageName);
	}
	
	public void createConnectionOneDirWithLock(String locationFrom,String locationTo, String passageName,String newPassageName, String unlockWithItem){
		passageBuilder.createConnectionOneDirWithLock(locations.get(locationFrom), locations.get(locationTo), passageName,newPassageName, unlockWithItem);
	}
	
	public void createActionOnObject(String itemName, String changeToItemName,String info){
		createActionOnObjectUseObject(itemName, null,changeToItemName,info);
	}

	public void createActionOnObjectUseObject(String itemName, String withItemName, String changeToItemName, String actionInfo){
		if( items.get(itemName)==null || items.get(changeToItemName)==null){
			throwGeneralBuilderException();
		}
		SimpleNameItem item = items.get(itemName);
		SimpleNameItem changeToItem = items.get(changeToItemName);
		if(withItemName==null){
			item.addNewItemOnAction(changeToItem, actionInfo);
		}else{
			if(!item.addPossibleInteractions(withItemName, changeToItem,actionInfo)){			
				throwGeneralBuilderException();
			}
		}
		items.put(changeToItemName, changeToItem);
		associatedItems.put(changeToItemName, changeToItem);
	}

	private GameWrapper createGameWrapper(Player player,final String locationName, final String itemName) {
		return new GameWrapperBasic(player) {
			
			@Override
			public boolean isPlayerWin() {
				if(locationName!=null){
					if(!player.getCurrentLocation().getName().equals(locationName)){
						return false;
					}
				}
				if(itemName!=null){
					for (Item item : player.getInventoryItems()) {
						if(item.getName().equals(itemName))return true;
					}
				}
				return false;
			}
		};
	}
	
	public void initGameWithFinishLocation(String startLocationName, String finishLocationName){
		initGameWithFinishLocationAndName(startLocationName, finishLocationName, null);
		
	}
	public void initGameWithFinishItem(String startLocationName, String finishWithItemName){
		initGameWithFinishLocationAndName(startLocationName, null, finishWithItemName);
		
	}
	public void initGameWithFinishLocationAndName(String startLocationName, String finishLocationName, String finishWithItemName){
		Location startLocation = locations.get(startLocationName);
		if(startLocation == null ){
			throwGeneralBuilderException();
		}
		gameWrapper = createGameWrapper(new PlayerBasic(startLocation),finishLocationName, finishWithItemName);
	}
	
	public void startGame(String gameName){
		
		if(gameWrapper == null){
			throw new RuntimeException("Game is not initialized");
		}
		CommandLineControll commandLineControll = new CommandLineControll(gameWrapper, null, null, gameName==null?"":gameName);
		commandLineControll.startGame();
	}
}
